/**
 * 
 */
package com.yullage.ae.attritioner;

import com.yullage.ae.core.Constants;
import com.yullage.ae.core.Attritioner;

/**
 * @author Yu-chun Huang
 * 
 */
public class LinearAttritioner implements Attritioner {
	private static final long serialVersionUID = 1L;

	private double attritionRate;
	private double threshold;

	public LinearAttritioner(double attritionRate, double threshold) {
		if (attritionRate > 1 || attritionRate < 0 || threshold > 1 || threshold < 0) {
			throw new IllegalArgumentException();
		}

		this.attritionRate = attritionRate;
		this.threshold = threshold;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yullage.ae.util.Attritioner#doAttrition(long, double)
	 */
	@Override
	public double doAttrition(long numNeurons, double energy) {
		if (numNeurons <= 0) {
			throw new IllegalArgumentException();
		}

		double fullEnergy = numNeurons * Constants.ENERGY_PER_NEURON;
		double intensity = energy / fullEnergy;

		if (intensity > 1 || intensity < -1) {
			throw new IllegalArgumentException();
		}

		double newIntensity = intensity * attritionRate;
		if (newIntensity >= threshold) {
			return attritionRate * energy;
		} else {
			return 0;
		}
	}

	public double getAttritionRate() {
		return attritionRate;
	}

	public void setAttritionRate(double attritionRate) {
		if (attritionRate > 1 || attritionRate < 0) {
			throw new IllegalArgumentException();
		}

		this.attritionRate = attritionRate;
	}

	public double getThreshold() {
		return threshold;
	}

	public void setThreshold(double threshold) {
		if (threshold > 1 || threshold < 0) {
			throw new IllegalArgumentException();
		}

		this.threshold = threshold;
	}
}
